package model;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;

import org.apache.log4j.Logger;

@Entity
public class Item {
	private static Logger logger = Logger.getLogger(Item.class);

	/* Atributos normais */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long item_id;

	private Long numeroDoPedido;

	private Date dataDaCriacao;

	private Long quantidade;

	/* Atributos de relacionamento */
	@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
	@JoinColumn(name = "notafiscal_id")
	private NotaFiscal notaFiscal;

	@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
	@JoinColumn(name = "departamento_id")
	private Departamento departamento;

	@ManyToMany(mappedBy = "items")
	private Collection<Produto> produtos = new ArrayList<Produto>();

	@ManyToMany(mappedBy = "items")
	private Collection<Cliente> clientes = new ArrayList<Cliente>();

	/* Construtor sem argumentos para o JPA */
	public Item() {
		/* Uma gambiarra oficial para descobrir quem chamou o construtor */
		try {
			throw new IllegalStateException();
		} catch (IllegalStateException e) {
			StackTraceElement[] stackTrace = e.getStackTrace();
			StackTraceElement stackTraceElement = stackTrace[1];
			if(stackTraceElement.getClassName().equals("sun.reflect.NativeConstructorAccessorImpl")){
				Item.logger.debug("JPA construindo um item");
			}else{
				Item.logger.info("Construindo um item");
			}
		}
	}

	/* RELACIONAMENTO COM NOTAFISCAL */
	public NotaFiscal getNotaFiscal() {
		return notaFiscal;
	}

	public void setNotaFiscal(NotaFiscal notaFiscal) {
		this.notaFiscal = notaFiscal;
	}

	/* RELACIONAMENTO COM DEPARTAMENTO */
	public Departamento getDepartamento() {
		return departamento;
	}

	public void setDepartamento(Departamento departamento) {
		this.departamento = departamento;
	}

	/* RELACIONAMENTO COM PRODUTO */
	public Collection<Produto> getProdutos() {
		return produtos;
	}

	public void addProduto(Produto produto) {
		this.produtos.add(produto);
	}

	/* RELACIONAMENTO COM CLIENTE */
	public Collection<Cliente> getClientes() {
		return clientes;
	}

	public void addCliente(Cliente cliente) {
		this.clientes.add(cliente);
	}

	/* GETTERS E SETTERS */
	public Date getDataDaCriacao() {
		return dataDaCriacao;
	}

	public void setDataDaCriacao(Date dataDaCriacao) {
		this.dataDaCriacao = dataDaCriacao;
	}

	public Long getItem_id() {
		return item_id;
	}

	public void setItem_id(Long item_id) {
		this.item_id = item_id;
	}

	public Long getNumeroDoPedido() {
		return numeroDoPedido;
	}

	public void setNumeroDoPedido(Long numeroDoPedido) {
		this.numeroDoPedido = numeroDoPedido;
	}

	public Long getQuantidade() {
		return quantidade;
	}

	public void setQuantidade(Long quantidade) {
		this.quantidade = quantidade;
	}

	/* Métodos reescritos */
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("\n--------------------" + this.getClass().getName() + "--------------------\n");
		builder.append("Quantidade: " + this.quantidade + "\n");
		builder.append("Data de criação: " + this.dataDaCriacao + "\n");
		builder.append("Número do pedido: " + this.numeroDoPedido);
		builder.append("\n--------------------" + this.getClass().getName() + "--------------------\n");
		return builder.toString();
	}
	
	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + ((item_id == null) ? 0 : item_id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Item other = (Item) obj;
		if (item_id == null) {
			if (other.item_id != null)
				return false;
		} else if (!item_id.equals(other.item_id))
			return false;
		return true;
	}
}
